#ifndef FIRSTFOLLOWGENERATOR_H
#define FIRSTFOLLOWGENERATOR_H

#include "defs.h"
#include <iostream>

class ContextFreeGrammar;

class FirstFollowGenerator
{
public:
    FirstFollowGenerator(ContextFreeGrammar * _parent);
    virtual ~FirstFollowGenerator();

    void Generate(const std::string & startSymbol = "");
    void Print(std::ostream & out = std::cout) const;
    std::pair <const FirstFollowMap *, const FirstFollowMap *>
        GetFirstFollow() const;

    void CollectFirst(FirstFollowSet & oldSet, const std::string & toCollect) const;
    bool CheckEpsilonInFirst(const std::string & str) const;

protected:

private:

    void GenerateFirst();
    void GenerateFollow(const std::string & startSymbol);
    void GeneratePredTable();

    void PrintFirst(std::ostream & out) const;
    void PrintFollow(std::ostream & out) const;
    void PrintPredTable(std::ostream & out) const;

    static bool MergeListKeepUnique(FirstFollowSet & to, const FirstFollowSet & from);

    const ContextFreeGrammar * parent;

    FirstFollowMap first, follow;
    PredMap predTable;
};

#endif // FIRSTFOLLOWGENERATOR_H
